package com.pomelo.tiku.managers;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import kotlin.jvm.Synchronized;

/**
 * Created by liuxiangwang
 * 2022/06/05.
 */
public class ThreadPoolManager {
    private static ThreadPoolManager mInstance;
    private ThreadPoolProxy mPoolProxy;
    private static final int mCorePoolSize = 5;
    private static final int mMaxmumPoolSize = 5;
    private static final int mKeepAliveTime = 5000;

    private ThreadPoolManager() {

    }

    public static ThreadPoolManager getInstance() {
        if (mInstance == null) {
            synchronized (ThreadPoolManager.class) {
                if (mInstance == null) {
                    mInstance = new ThreadPoolManager();
                }
            }
        }
        return mInstance;
    }

    /**
     * 创建线程池
     * @return
     */
    public synchronized ThreadPoolProxy createThreadPool() {
        if (mPoolProxy == null) {
            mPoolProxy = new ThreadPoolProxy(mCorePoolSize, mMaxmumPoolSize, mKeepAliveTime);
        }
        return mPoolProxy;
    }

    public class ThreadPoolProxy {
        private ThreadPoolExecutor pool;
        private int corePoolSize; //线程数
        private int maximumPoolSize; //线程满了后额外开的线程窗口
        private long keepAliveTime;//没有线程执行时存活时间

        public ThreadPoolProxy(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.keepAliveTime = keepAliveTime;
        }

        /**
         * 执行线程
         *
         * @param runnable
         */
        public void execute(Runnable runnable) {
            if (pool == null) {
                //最多可有多少个线程排队
                BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(10);
                pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, workQueue);
            }
            pool.execute(runnable);
        }

        /**
         * 取消线程
         *
         * @param runnable
         */
        public void cancel(Runnable runnable) {
            if (pool != null) {
                pool.remove(runnable);
            }
        }
    }
}
